home *** CD-ROM | disk | FTP | other *** search
/ The X-Philes (2nd Revision) / The X-Philes Number 1 (1995).iso / xphiles / hp48hor1 / sunclk.src < prev    next >
Text File  |  1991-10-19  |  20KB  |  739 lines

  1. %%HP: T(3)A(R)F(.);
  2. @ SUNCLK, by James Elliott
  3. @ Directory: SunClk
  4. @ Checksum: # 40750d  Bytes: 8805.5
  5. DIR
  6.   Now
  7. @ Put the current date and time into TM and DT, convert to Julian
  8. @ date/time, and call SunClk, the driver program.
  9.     \<< DATE TIME
  10. 'TM' STO 'DT' STO
  11. GTime 1 'STAT' STO
  12. SunClk
  13.     \>>
  14.   Then
  15. @ Create a temporary menu that allows specification of an arbitrary
  16. @ date and time, and display the current settings. Trap errors in case
  17. @ an invalid date or time is entered, so garbage isn't left on the
  18. @ stack.
  19.     \<< { { ">DATE"
  20. @ Menu key for setting the date to view.
  21.       \<< \-> i
  22.         \<< DT \-> d
  23.           \<< i
  24.             IF DUP
  25. DUP IP ==
  26. @ If only the month was entered, default the rest from the previous
  27. @ setting.
  28.             THEN d
  29. FP +
  30.             ELSE
  31.               IF
  32. DUP FP 100 * DUP IP
  33. ==
  34. @ Similarly, if the year is missing, provide the default.
  35.               THEN
  36. d 100 * FP 100 / +
  37.               END
  38.             END
  39. 'DT' STO
  40. @ Update the date to reflect their changes, fixing things if there is
  41. @ an error.
  42.             IFERR
  43. ShwTm
  44.             THEN
  45. ERRM 3 DISP 2 WAIT
  46. DROP DROP d 'DT'
  47. STO ShwTm
  48.             END
  49.           \>>
  50.         \>>
  51.       \>> } { ">TIME"
  52. @ Menu key for setting the time to view. Very similar to above.
  53.       \<< \-> i
  54.         \<< TM \-> t
  55.           \<< i 'TM'
  56. STO
  57.             IFERR
  58. ShwTm
  59.             THEN
  60. ERRM 3 DISP 2 WAIT
  61. DROP DROP t 'TM'
  62. STO ShwTm
  63.             END
  64.           \>>
  65.         \>>
  66.       \>> } { "A/PM"
  67. @ Toggle AM vs. PM
  68.       \<< TM 12 - DUP
  69.         IF 0 <
  70.         THEN 24 +
  71.         END 'TM'
  72. STO ShwTm
  73.       \>> } { } { } {
  74. "Go"
  75. @ Use the specified time; convert it to Julian time and call SunClk,
  76. @ the driver program, restoring the normal menu.
  77.       \<< 0 MENU
  78. GTime 0 'STAT' STO
  79. SunClk
  80.       \>> } } TMENU
  81. @ Okay, the temporary menu is built; now show what the default time
  82. @ and date are (these are the ones used for the last display.)
  83. ShwTm
  84.     \>>
  85.  
  86.  
  87. @ Provide brief instructions. Blank the menu while waiting for
  88. @ keypresses between screens.
  89.   Help
  90.     \<< CLLCD { }
  91. TMENU
  92. "Press NOW for current"
  93. 1 DISP
  94. "daylight map, or THEN"
  95. 2 DISP
  96. "to pick a day & time."
  97. 3 DISP
  98. "Set TZ to your time"
  99. 5 DISP
  100. "zone (eg. CDT = -5)."
  101. 6 DISP -1 WAIT DROP
  102. CLLCD
  103. "To interrupt, press"
  104. 1 DISP
  105. "any key other than"
  106. 2 DISP
  107. "ON/ATTN, and it will"
  108. 3 DISP
  109. "stop in a few seconds"
  110. 4 DISP
  111. "and clean up." 5
  112. DISP 0 WAIT DROP
  113. CLLCD
  114. "'NOW' updates the map"
  115. 1 DISP
  116. "continually until you"
  117. 2 DISP
  118. "interrupt it, 'THEN'"
  119. 3 DISP
  120. "draws a map and ends."
  121. 4 DISP 0 MENU 3
  122. FREEZE
  123.     \>>
  124.  
  125.  
  126. @ Provide brief credits. Blank the menu while waiting for
  127. @ keypresses between screens.
  128.   About
  129.     \<< CLLCD { }
  130. TMENU
  131. "HP 48SX implementation"
  132. 1 DISP
  133. "by James J. Elliott"
  134. 2 DISP
  135. "<elliott@cs.wisc.edu>"
  136. 3 DISP
  137. "Public domain; share"
  138. 5 DISP "and enjoy!"
  139. 6 DISP -1 WAIT DROP
  140. CLLCD
  141. "Based on a SunView"
  142. 1 DISP
  143. "program by:" 2
  144. DISP "John Walker"
  145. 4 DISP
  146. "<kelvin@acad.uu.net>"
  147. 5 DISP 0 WAIT DROP
  148. CLLCD
  149. "Algorithms found in"
  150. 1 DISP
  151. "'Astronomical Formulae"
  152. 2 DISP
  153. "for Calculators' by"
  154. 3 DISP
  155. "Jean Meeus, Third"
  156. 4 DISP
  157. "Edition, 1985." 5
  158. DISP 3 FREEZE 0
  159. MENU
  160.     \>>
  161.  
  162.  
  163. @ This variable contains your current time zone. My default is Central
  164. @ Daylight savings Time, or 5 hours earlier than UTC.
  165.   TZ -5
  166.  
  167. @ This variable determines how detailed (and therefore slow) the
  168. @ computation of the daylight bands' width is. In projecting the
  169. @ sunlight region over the daylight hemisphere, this many different
  170. @ bands are computed, and linear interpolation is used between them up
  171. @ to the resolution of the graphics display. Note that it does not
  172. @ make sense to set this higher than 62, since only 62 values are
  173. @ stored! The lower the number, the chunkier the display, but the
  174. @ faster arbitrary dates can be displayed. It doesn't really affect
  175. @ the speed of ongoing updates, since this computation is only done
  176. @ when the sun's declination drifts beyond a threshold from its
  177. @ current value.
  178.   Res 40
  179.  
  180. @ This is the threshold referred to above.
  181.   Thres .5
  182.  
  183. @ This is just a band of black used in drawing the sunlight (with
  184. @ GXOR). It's much faster than using LINE.
  185.   STRIP
  186. GROB 131 1 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
  187.  
  188. @ Here's the world map.
  189.   World
  190. GROB 126 64 FFFFFFF30000008FFFFFFEFFFFFFFFF3FFFFFF1000CFF18F10F00CF30FFFFFF3FFFF7000008FF7EF18FF38F30CF1EFF3FFFF70000E3FF1EFFFFF002840018FF3E30E1000007CF07EF0CF010FF5000892C8F00000004C78FF340000CF9FFF910208FF744000CC038F1008F30FFFFFFF72389FF0C000E0E3C7800EFFFFFFFFF132F000E18971E1FFF0000FFFFFFFF70083F3C3C72324CFFFF8004FFFFF9FF1F0F370FF8F7E0D1FFF700CF3FFCF1EF1E8F30EFF0F74270FFF70FFF9FFDF3FF7ECF3FFFF3E17020EFFF9FF7D7EFFFFF36EF3FFFF7F73014EFFFB0F03270FFFF10FF3FFFF7F7F00EFFF7006122FCFFF74CFF3FFFF7FFF88FFFE730024CFFFF703FFF3FFFF7EFFFEFFF8700184EFFFF701FFF3FFFFF8FF3EFFFF7883BFFFFFF720FFF3FFFFF3F78FFFFF4F3083FFFFF76EFFF3FFFFF3E09FFFFF1FFF93CFFFFFEFFFF3FFFFF3CE3FFFFF9FFF170CFFF7EFFFF3F7FFFF8E0FFFFFCFFF0F81F870EFFFF3F7EFFFB000FFFFCFFF3E93727EEFFFF3FFFFFF3040EFFFDFFF7EC73766EFFFF3FFFFFFF1CFFFFFCF3F70E7A346CFFFF3FFFFFFEFC0CFFF9F3FF1FF8B06CFFBD3FFFFFFEF008FFFBBFFF7FF8B078FFBD3FFFFFFFF3F3EFF30CFB3FF93019FFFF3FFFFFFFF7FFCFFFFCF89FFF7001FFFF3FFFFFFF33FF0FFFFCE8CFFF7820AFF73FFFFFFFB3FF4CFFFDE4EFFFF00002F73FFFFFFFFBFFF9FFF9F6FFFFF10E90EF3FFFBFFFF3FFFBF9FB76FFFFF708388F3FFFBFFFF7EFF9FFFBF64FFFFF7448FF3FFFFFFFFFAFFDFFFBFC0FFFFFF15EFE3FFFDFFFFF8FFDFFC3300FFFFFFC1CFC3FFFDFFFFFBFFCFFF3BB1DFFFF3EF97C3FFFFFFFFFBF3EFFF3FB9DFFFF9FF3FE3FFFFFFFFFBF9FFFF7F99FFFFF9FF7FF3FFFFFFFFF9F9FFFF7ECFFFFFF1E17FF3FFFFFFFFFDFCFFFFF6EFFFFFF3107FF3FFFFFFFFFD3EFFFFF0FFFFFFF3C93F33FFFFFFFFFD3FFFFFFFFFFFFFFFF18F32FFFFFFFFFD8FFFFFFFFFFFFFFFFFCF32FFFFFFFFFCEFFFFFFFFFFFFFFFFFCF03FFFFFFFFF4EFFFFFFFFFFFFFFFFFFF83FFFFFFFFF4FFFFFFFFFFFFFFFFFFFFE3FFFFFFFFF09FFFFFFFFFFFFFFFFFFFF3FFFFFFFFF0EF9FFFFFFFFFFFFFFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFFFFFFFFF9FFFFFFFFFFFFFFFFFFFF3FFFFFFFFF7CFFFFFFFFF0E300000EFF3FFFFFFFF70CFFFFF7F00E18FFFFF08F3FFFFFF7040DFFF7000EFFFFFFFFFF3C3FFF1000C08CFF30FFFFFFFFFFFFFF3C3F70C9FFFF70E38FFFFFFFFFFFFFFF3E3F90FFFFFFFF1CFFFFFFFFFFFFFFFF1E3F7EFFFFFFFFFFFFFFFFFFFFFFFFFF1028F9FFFFFFFFFFFFFFFFFFFFFFFFFF7C3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF3
  191.  
  192. @ (End of amendments)
  193.  
  194. @ This reverses the pixels of a region of the line being built up,
  195. @ starting at the pixel in level 2, and ending at the pixel in level
  196. @ 1. It's called by XSpan, below.
  197.   XLine
  198.     \<< \-> s f
  199.       \<< STRIP f 1 +
  200. s - R\->B # 0d 2
  201. \->LIST STRIP GXOR s
  202. 2 + R\->B # 0d 2
  203. \->LIST SWAP GXOR
  204.       \>>
  205.     \>>
  206.  
  207. @ Reverse a region of the line, centered on the pixel in level 1, and
  208. @ twice the length specified in level 2. Handles wrapping off the left
  209. @ edge if needed.
  210.   XSpan
  211.     \<< \-> l n
  212.       \<< l 126 MOD
  213. 'l' STO
  214.         IF l n +
  215. 126 >
  216.         THEN l 125
  217. XLine 0 l n + 127 -
  218. XLine
  219.         ELSE l l n
  220. + 1 - XLine
  221.         END
  222.       \>>
  223.     \>>
  224.  
  225.  
  226. @ Draw the time at the bottom of the map.
  227.   XTime
  228.     \<< \-> s
  229.       \<< s 1 \->GROB
  230. DUP SIZE DROP \-> o w
  231.         \<< PICT 131
  232. w - 2 / # 59d 2
  233. \->LIST o GXOR
  234.         \>>
  235.       \>>
  236.     \>>
  237.  
  238.  
  239. @ Update the sunlit region display if necessary, and the time display
  240. @ if appropriate. Takes the pixel location of noon in level 1.
  241.   Draw
  242.     \<< \-> n
  243.       \<< 0 255 \-> w o
  244.         \<<
  245. @ Is this an update, or the first display? If an update, set flag 6,
  246. @ so that the old lines will be taken into account.
  247.           IF 'OTAB'
  248. VTYPE 0 \>=
  249.           THEN 6 SF
  250. @ Has the sun moved, as far as the resolution of the map is concerned?
  251. @ If so, set flag 7.
  252.             IF n
  253. ONOON \=/
  254.             THEN 7
  255. SF
  256.             ELSE 7
  257. CF
  258.             END
  259.           ELSE 6 CF
  260. 7 CF
  261.           END 1 64
  262. @ Loop over the whole map, one horizontal band at a time.
  263.           FOR i
  264.             IF 6
  265. FS?
  266. @ If it's an update, determine what the width was last time.
  267.             THEN
  268. OTAB i DUP SUB NUM
  269. 'o' STO
  270.             END
  271. @ Figure out the width of sunlight at this latitude, by looking it up
  272. @ in the width table built by PrjIll.
  273. WTAB i DUP SUB NUM
  274. 'w' STO
  275. @ If the sun has moved or the width has changed, we need to update
  276. @ this band.
  277.             IF o w
  278. \=/ 7 FS? OR
  279.             THEN
  280. @ Create a blank line in which the regions which need to change will
  281. @ be marked.
  282. # 131d # 1d BLANK
  283. @ If there was an old sunlit band, we'll erase it.
  284.               IF o
  285. 255 <
  286.               THEN
  287. ONOON o - 126 + 126
  288. MOD o 2 * XSpan
  289.               END
  290. @ If there is a new sunlit band, draw it.
  291.               IF w
  292. 255 <
  293.               THEN
  294. n w - 126 + 126 MOD
  295. w 2 * XSpan
  296.               END
  297. @ Take the net result of the above two operations and apply it to the
  298. @ actual map in one fast GXOR, so there's no flicker.
  299. PICT SWAP # 0d i 1
  300. - R\->B 2 \->LIST SWAP
  301. GXOR
  302.             END
  303. @ If the user wants to stop, record that fact and abort the loop.
  304.             IF KEY
  305.             THEN
  306. DROP -1 'STAT' STO
  307. 63 'i' STO
  308.             END
  309.           NEXT
  310.         \>>
  311.       \>>
  312. @ If the clock display is enabled, draw the time at the bottom of the
  313. @ map (erasing the old time first, since GXOR is being used.)
  314.       IF -40 FS?
  315.       THEN OSTR
  316. XTime DT TM TSTR
  317. DUP 'OSTR' STO
  318. XTime
  319.       END
  320.     \>>
  321.  
  322.  
  323. @ Main driver program: Compute the relevant astronomical variables and
  324. @ then draw the map.
  325.   SunClk
  326. @ First make sure the right mathematical modes are in effect.
  327.     \<< RCLF -19 CF
  328. -15 CF -16 CF -17
  329. SF -18 CF CLLCD
  330. @ Display an explanatory screen during the initial computation.
  331. "       SunClock" 1
  332. DISP
  333. "  Figuring widths of"
  334. 3 DISP
  335. "  daylight bands."
  336. 4 DISP
  337. "[Preliminaries]" 7
  338. DISP PICT PURGE
  339. @ Put the completely dark map into PICT.
  340. PICT { # 2d # 0d }
  341. World REPL ""
  342. @ Note that no time string has yet been displayed.
  343. 'OSTR' STO
  344. @ This is the animation loop; if "NOW" was pressed, it will be
  345. @ executed multiple times.
  346.       DO JTime 0 0
  347. 0 0 \-> jt gt ra dec
  348. xl
  349.         \<< jt DUP
  350. GMST 'gt' STO 0
  351. @ Figure out the location of the sun at the specified instant.
  352. SunPos DROP DROP
  353. 'dec' STO 'ra' STO
  354. @ We only care about the angular information.
  355.           IF dec
  356. @ If the declination has changed more than the threshold value, or if
  357. @ it has changed sign, recompute the table of daylight widths.
  358. OldDec - ABS Thres
  359. \>= dec SIGN OldDec
  360. SIGN \=/ OR
  361.           THEN dec
  362. PrjIll
  363.           END
  364. @ Unless the user has already hit a key (requesting termination), draw
  365. @ the resulting map.
  366.           IF STAT 0
  367. \>=
  368.           THEN {
  369. # 0d # 0d } PVIEW
  370. @ Figure out the longitude of noon.
  371. ra gt 15 * - 180 +
  372. FixAng 126 * 360 /
  373. @ Draw the current map.
  374. FLOOR DUP Draw
  375. @ Keep track of the last location of noon.
  376. 'ONOON' STO
  377.           END
  378.         \>>
  379. @ If the user has hit a key, end the animation loop if it was active.
  380.         IF KEY
  381.         THEN DROP
  382. -1 'STAT' STO
  383.         END
  384. @ If we're animating, update the date and time and record the old
  385. @ widths table so they can be erased properly on the next update.
  386.         IF STAT 0 >
  387.         THEN DATE
  388. TIME 'TM' STO 'DT'
  389. STO GTime WTAB
  390. 'OTAB' STO
  391.         END
  392. @ If we're animating, loop back and recompute/redraw.
  393.       UNTIL STAT 0
  394. \<=
  395. @ Get rid of extraneous variables.
  396.       END STAT {
  397. OTAB ONOON OSTR
  398. PPAR STAT } PURGE
  399. @ If the user hasn't hit a key but we're ending because "THEN" was the
  400. @ calling program (one-shot date display), freeze the screen so the
  401. @ user can enjoy their map.
  402.       IF 0 \>=
  403.       THEN 7 FREEZE
  404.       END STOF
  405.     \>>
  406.  
  407.  
  408. @ Figure out what widths of sunlight fall on the latitude bands of the
  409. @ map. Given the sun's declination in level 1.
  410.   PrjIll
  411.     \<< \-> dec
  412.       \<< 0 0 0 0 0 0
  413. 0 0 0 0 0 0 0 0 0 \->
  414. i ilon ilat lilon
  415. lilat xt m x y z th
  416. lon lat s c
  417. @ Initialize the width table to "darkness". This was originally an
  418. @ array, but 64 real numbers took too much space, so I changed it to a
  419. @ string. 255 means no light, other numbers are 1/2 the width to
  420. @ illuminate.
  421.         \<< "" 1 64
  422.           FOR c 255
  423. CHR +
  424.           NEXT
  425. @ Flag 6 is set the first time through, so interpolation isn't attempted.
  426. 'WTAB' STO 6 SF dec
  427. @ Build the transformation for the declination.
  428. D\->R NEG SIN 's' STO
  429. dec D\->R NEG COS 'c'
  430. STO \pi \->NUM 2 / NEG
  431. 'th' STO
  432. @ Increment over a semicircle of illumination.
  433.           DO s NEG
  434. @ Transform the point through the declination rotation.
  435. th SIN * 'x' STO th
  436. COS 'y' STO c th
  437. SIN * 'z' STO y x
  438. @ Transform the resulting coordinate through the map projection to
  439. @ obtain screen coordiantes.
  440. ATAN2 R\->D 'lon' STO
  441. z ASIN R\->D 'lat'
  442. STO 62 lat 90 +
  443. .344444444444 * -
  444. IP 'ilat' STO lon
  445. .35 * IP 'ilon' STO
  446.             IF 6
  447. FS?C
  448.             THEN
  449. @ First time through; just record the previous coordinates.
  450. ilon 'lilon' STO
  451. ilat 'lilat' STO
  452.             ELSE
  453. @ Interpolate between the current and previous points if we've jumped
  454. @ more than one map line down.
  455.               IF
  456. lilat ilat ==
  457.               THEN
  458. WTAB 62 ilat - ilon
  459. 1 MAX CHR REPL
  460. 'WTAB' STO
  461.               ELSE
  462. ilon lilon - ilat
  463. lilat - / 'm' STO
  464. lilat 'i' STO
  465. WHILE i ilat \=/
  466. REPEAT lilon i
  467. lilat - m * .5 +
  468. FLOOR + 'xt' STO
  469. WTAB 62 i - xt 1
  470. MAX CHR REPL 'WTAB'
  471. STO ilat lilat -
  472. SIGN 'i' STO+
  473. END
  474.               END
  475. ilon 'lilon' STO
  476. ilat 'lilat' STO
  477.             END \pi
  478. @ Back at the outer loop; give the user feedback about how the
  479. @ computation is progressing.
  480. \->NUM Res / 'th'
  481. STO+ "[" th \pi \->NUM
  482. 2 / + \pi \->NUM / 100
  483. * 100 MIN FLOOR
  484. \->STR + "%]" + 7
  485. DISP
  486. @ If the user wishes to terminate this computation, record the fact
  487. @ and abort the loop.
  488.             IF KEY
  489.             THEN
  490. DROP 3 'th' STO -1
  491. 'STAT' STO 1000
  492. 'OldDec' STO
  493.             END
  494. @ Keep computing until the full semicircle is done.
  495.           UNTIL th
  496. \pi \->NUM 2 / .001 + >
  497.           END
  498. @ One edge of the map is fully illuminated, but may have been missed
  499. @ in the above loop, so tweak the widths at that end.
  500.           IF dec 0
  501. <
  502. @ South pole in daylight
  503.           THEN -1
  504. 64
  505.           ELSE 1 1
  506. @ North pole in daylight.
  507.           END
  508. 'ilat' STO 'lilat'
  509. STO
  510. @ Don't bother if the user's already aborting.
  511.           IF STAT 0
  512. \>=
  513. @ Loop from the edge of the map until a non-dark line is found,
  514. @ illuminating as you go.
  515.           THEN ilat
  516. 31
  517.             FOR j
  518.               IF
  519. WTAB j DUP SUB NUM
  520. 255 \=/
  521.               THEN
  522. DO WTAB j 63 CHR
  523. REPL 'WTAB' STO
  524.   IF j ilat ==
  525.   THEN lilat 'j'
  526. STO
  527.   END lilat NEG 'j'
  528. STO+
  529. UNTIL j 0 ==
  530. END 31 'j' STO
  531.               END
  532. lilat
  533.             STEP
  534. @ All done; keep track of the declination value used in this
  535. @ computation, so it can be avoided next time if the current
  536. @ declination is close enough.
  537. dec 'OldDec' STO
  538.           END
  539.         \>>
  540.       \>>
  541.     \>>
  542.  
  543.  
  544. @ Calculate the position of the sun. Level 2 contains the Julian time
  545. @ of the instant for which the position is desired, and level 1 should
  546. @ be nonzero if the apparent position (corrected for nutation and
  547. @ aberration) is desired.
  548. @ The Sun's longitudinal position (in degrees) is returned in level 4;
  549. @ divide by 15 to get hours. The declination is returned in level 3.
  550. @ The radius vector (in astronomical units) is returned in level 2,
  551. @ and the Sun's longitude (true or apparent, as desired) is returned
  552. @ as degrees in level 1.
  553.   SunPos
  554.     \<< \-> jd ap
  555.       \<< 0 0 0 0 0 0
  556. 0 0 0 0 0 0 0 0 0 \->
  557. t t2 t3 l m e ea v
  558. th om eps ra dec rv
  559. slong
  560.         \<< jd
  561. 2415020 - 36525 /
  562. @ Convert time to Julian centuries of 36525 ephemeris days, measured
  563. @ from the epoch 1900 January 0.5 ET.
  564. DUP 't' STO DUP DUP
  565. * DUP 't2' STO *
  566. 't3' STO 279.69668
  567. 36000.76892 t * +
  568. .0003025 t2 * +
  569. FixAng 'l' STO
  570. @ 'l' gets the geometric mean longitude of the Sun, referred to the
  571. @ mean equinox of the date. Now compute the sun's mean anomaly.
  572. 358.47583
  573. 35999.04975 t * +
  574. .00015 t2 * -
  575. .0000033 t3 * -
  576. FixAng 'm' STO
  577. @ Now take the eccentricity of the Earth's orbit into account.
  578. .01675104 .0000418
  579. t * - .000000126 t2
  580. * - 'e' STO m e
  581. @ Compute the eccentric anomaly.
  582. Kepler 'ea' STO 1 e
  583. @ Compute the true anomaly.
  584. + 1 e - / \v/ ea 2 /
  585. TAN * ATAN R\->D 2 *
  586. FixAng 'v' STO l v
  587. @ Compute the sun's true longitude.
  588. + m - 'th' STO
  589. @ Obliquity of the ecliptic:
  590. 23.452294 .0130125
  591. t * - .00000164 t2
  592. * - .000000503 t3 *
  593. + 'eps' STO
  594.           IF ap
  595. @ Corrections for sun's apparent longitude, if desired.
  596.           THEN
  597. 259.18 1934.142 t *
  598. - FixAng 'om' STO
  599. .00569 .00479 om
  600. D\->R SIN * - NEG
  601. 'th' STO+ .00256 om
  602. D\->R COS * 'eps'
  603. STO+
  604.           END th
  605. @ Record sun's longitude and radius vector, then compute coordinates.
  606. 'slong' STO
  607. 1.0000002 1 e e * -
  608. * 1 e v D\->R COS * +
  609. / 'rv' STO eps D\->R
  610. COS th D\->R SIN * th
  611. D\->R COS ATAN2 R\->D
  612. FixAng 'ra' STO eps
  613. D\->R SIN th D\->R SIN
  614. * ASIN R\->D 'dec'
  615. STO ra dec rv slong
  616.         \>>
  617.       \>>
  618.     \>>
  619.  
  620.  
  621. @ Solve the equation of Kepler.
  622.   Kepler
  623.     \<< \-> m ecc
  624.       \<< 0 0 \-> e d
  625.         \<< m D\->R DUP
  626. 'm' STO 'e' STO
  627.           DO e e
  628. SIN ecc * - m - 'd'
  629. STO d 1 e COS ecc *
  630. - / NEG 'e' STO+
  631.           UNTIL d
  632. ABS .000001 \<=
  633.           END e
  634.         \>>
  635.       \>>
  636.     \>>
  637.  
  638. @ Compute arctan(y/x), with y in level 2 and x in level 1. Returns
  639. @ appropriate quadrant treating y and x as rectangular coordinates
  640. @ being converted to polar coordinates.
  641.   ATAN2
  642.     \<< SWAP \->V2 -16
  643. SF V\-> -16 CF SWAP
  644. DROP
  645.     \>>
  646.  
  647. @ Translate a big angle back in to the range 0-360 degrees.
  648.   FixAng
  649.     \<< DUP 360 /
  650. FLOOR 360 * -
  651.     \>>
  652.  
  653. @ Show the currently chosen date and time and prompt the user for
  654. @ their next action (used by the "THEN" submenu).
  655.   ShwTm
  656.     \<< CLLCD DT TM
  657. TSTR 4 DISP
  658. "Choose time, push GO"
  659. 3 DISP 2 FREEZE
  660.     \>>
  661.   GMST
  662.     \<< \-> jd
  663.       \<< jd .5 +
  664. FLOOR .5 - 2415020
  665. - 36525 / 0 \-> t th0
  666.         \<< 6.6460656
  667. 2400.051262 t * +
  668. .00002581 t t * * +
  669. 'th0' STO jd .5 +
  670. DUP FLOOR - 24 *
  671. 1.002737908 * th0 +
  672. DUP 24 / FLOOR 24 *
  673. -
  674.         \>>
  675.       \>>
  676.     \>>
  677.  
  678. @ Convert the chosen date and time to Greenwich time.
  679.   GTime
  680.     \<< RCLF -42 CF
  681. DT 'GD' STO TM TZ -
  682. DUP
  683.       IF 24 \>=
  684.       THEN 24 - GD
  685. 1 DATE+ 'GD' STO
  686.       END 'GT' STO
  687. STOF
  688.     \>>
  689.  
  690. @ Compute the chosen Julian time, as a date and day fraction.
  691.   JTime
  692.     \<< JDate .5 - GT
  693. HMS\-> 24 / +
  694.     \>>
  695.  
  696. @ Compute the Julian date for the chosen date.
  697.   JDate
  698.     \<< GD DUP IP
  699. SWAP FP 100 * DUP
  700. IP SWAP FP 10000 *
  701. 0 \-> m d y c
  702.       \<<
  703.         IF 'm>2'
  704.         THEN -3 'm'
  705. STO+
  706.         ELSE 9 'm'
  707. STO+ -1 'y' STO+
  708.         END y 100 /
  709. IP DUP 'c' STO 100
  710. * NEG 'y' STO+ d c
  711. 146097 * 4 / IP + y
  712. 1461 * 4 / IP + m
  713. 153 * 2 + 5 / IP +
  714. 1721119 +
  715.       \>>
  716.     \>>
  717.  
  718. @ Holds the currently chosen time:
  719.   TM 22.3138814208
  720.  
  721. @ Holds the currently chosen date:
  722.   DT 11.151991
  723.  
  724. @ Greenwich time and date for above values:
  725.   GT 3.3138814208
  726.   GD 11.161991
  727.  
  728. @ Stores the declination for the last computed daylight width table.
  729.   OldDec
  730. -18.5917760031
  731.  
  732. @ The most recently computed width table, as a string for space
  733. @ reasons (about 70 bytes instead of 500, and there are two of these
  734. @ around while animation is active.)
  735.   WTAB
  736. C$ 64 \255\255\255\255\255\255
  737.    !!!"""##$$$%&'')*+,/5?????????
  738. END
  739.